package cn.fx.framework.utils;

import java.text.DecimalFormat;

/**
 * 金融数字转换为大写的工具类
 *
 * @author fxcn
 * @version 1.0.0.1
 */
final class RMBConvertor {
    private static final String DXSZ = "零壹贰叁肆伍陆柒捌玖";
    private static final String DXDW = "毫厘分角元拾佰仟万拾佰仟亿拾佰仟万兆拾佰仟万亿京拾佰仟万亿兆垓";
    private static final String SCDW = "元拾佰仟万亿京兆垓";

    /**
     * 转换整数为大写金额
     * 最高精度为垓，保留小数点后4位，实际精度为亿兆已经足够了，理论上精度无限制，如下所示：
     * 序号:...30.29.28.27.26.25.24  23.22.21.20.19.18  17.16.15.14.13  12.11.10.9   8 7.6.5.4  . 3.2.1.0
     * 单位:...垓兆亿万仟佰拾        京亿万仟佰拾       兆万仟佰拾      亿仟佰拾     万仟佰拾元 . 角分厘毫
     * 数值:...1000000               000000             00000           0000         00000      . 0000
     * 下面列出网上搜索到的数词单位：
     * 元、十、百、千、万、亿、兆、京、垓、秭、穰、沟、涧、正、载、极
     *
     * @param capValue 整数值
     * @return 返回大写金额
     */
    private static String convertIntToUppercaseAmount(String capValue) {
        String currCap = "";    //当前金额
        String capResult = "";  //结果金额
        String currentUnit = "";//当前单位
        String resultUnit = ""; //结果单位
        int prevChar = -1;      //上一位的值
        int currChar = 0;       //当前位的值
        int posIndex = 4;       //位置索引，从"元"开始

        if (Double.parseDouble(capValue) == 0d) return "";
        for (int i = capValue.length() - 1; i >= 0; i--) {
            currChar = Integer.parseInt(capValue.substring(i, i + 1));
            if (posIndex > 30) {
                //已超出最大精度"垓"。注：可以将30改成22，使之精确到兆亿就足够了
                break;
            } else if (currChar != 0) {
                //当前位为非零值，则直接转换成大写金额
                currCap = DXSZ.substring(currChar, currChar + 1) + DXDW.substring(posIndex, posIndex + 1);
            } else {
                //防止转换后出现多余的零,例如：3000020
                switch (posIndex) {
                    case 4:
                        currCap = "元";
                        break;
                    case 8:
                        currCap = "万";
                        break;
                    case 12:
                        currCap = "亿";
                        break;
                    case 17:
                        currCap = "兆";
                        break;
                    case 23:
                        currCap = "京";
                        break;
                    case 30:
                        currCap = "垓";
                        break;
                    default:
                        break;
                }
                if (prevChar != 0) {
                    if (currCap != "") {
                        if (currCap != "元") currCap += "零";
                    } else {
                        currCap = "零";
                    }
                }
            }
            //对结果进行容错处理
            if (capResult.length() > 0) {
                resultUnit = capResult.substring(0, 1);
                currentUnit = DXDW.substring(posIndex, posIndex + 1);
                if (SCDW.indexOf(resultUnit) > 0) {
                    if (SCDW.indexOf(currentUnit) > SCDW.indexOf(resultUnit)) {
                        capResult = capResult.substring(1);
                    }
                }
            }
            capResult = currCap + capResult;
            prevChar = currChar;
            posIndex += 1;
            currCap = "";
        }
        return capResult;
    }

    /**
     * 转换小数为大写金额
     *
     * @param capValue 小数值
     * @param addZero  是否增加零位
     * @return 返回大写金额
     */
    private static String convertDecToUppercaseAmount(String capValue, boolean addZero) {
        String currCap = "";
        String capResult = "";
        int prevChar = addZero ? -1 : 0;
        int currChar = 0;
        int posIndex = 3;

        if (Integer.parseInt(capValue) == 0) return "";
        for (int i = 0; i < capValue.length(); i++) {
            currChar = Integer.parseInt(capValue.substring(i, i + 1));
            if (currChar != 0) {
                currCap = DXSZ.substring(currChar, currChar + 1) + DXDW.substring(posIndex, posIndex + 1);
            } else {
                if (Integer.parseInt(capValue.substring(i)) == 0) {
                    break;
                } else if (prevChar != 0) {
                    currCap = "零";
                }
            }
            capResult += currCap;
            prevChar = currChar;
            posIndex -= 1;
            currCap = "";
        }
        return capResult;
    }

    /**
     * 将一个金额double类型数据转换为大写人民币格式
     * @param value
     * @return
     */
    public static String RMBAmount(double value) {
        String capResult = "";
        String capValue = new DecimalFormat("#.####").format(value);//String.format("#.0000", value);//String.Format("{0:f4}", value);       //格式化
        int dotPos = capValue.indexOf(".");                     //小数点位置
        boolean addInt = (Integer.parseInt(capValue.substring(dotPos + 1)) == 0);//是否在结果中加"整"
        boolean addMinus = (capValue.substring(0, 1) == "-");      //是否在结果中加"负"
        int beginPos = 0;

        //开始位置
        String capInt = capValue.substring(beginPos, beginPos + dotPos);   //整数
        if (addMinus) capInt = capInt.substring(1);//如果是负数将负号去掉
        String capDec = capValue.substring(dotPos + 1);         //小数

        if (dotPos > 0) {
            capResult = convertIntToUppercaseAmount(capInt) +
                    convertDecToUppercaseAmount(capDec, Double.parseDouble(capInt) != 0 ? true : false);
        } else {
            capResult = convertIntToUppercaseAmount(capDec);
        }
        if (addMinus) capResult = "负" + capResult;
        if (addInt) capResult += "整";
        return capResult;
    }

    public static void main(String[] args) {
//        System.out.println(RMBAmount(123456789.1234));
//        System.out.println(RMBConvertor.convertIntToUppercaseAmount("12318976"));
//        System.out.println(RMBConvertor.convertDecToUppercaseAmount("12300", true));
//        System.out.println(RMBAmount(0.1234));
    }
}
